package com.chenfan.magic.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.chenfan.magic.enums.DatabaseType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author admin
 */
@Configuration
@MapperScan(value = "com.chenfan.**.dao.**", sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourcesConfig {

    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private Integer initialSize;
    private Integer maxActive;
    private Integer minIdle;
    private Integer maxWait;

    @Value("${spring.datasource.druid.clickhouse.driver-class-name}")
    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    @Value("${spring.datasource.druid.clickhouse.url}")
    public void setUrl(String url) {
        this.url = url;
    }

    @Value("${spring.datasource.druid.clickhouse.username}")
    public void setUsername(String username) {
        this.username = username;
    }

    @Value("${spring.datasource.druid.clickhouse.password}")
    public void setPassword(String password) {
        this.password = password;
    }

    @Value("${spring.datasource.druid.clickhouse.initial-size}")
    public void setInitialSize(Integer initialSize) {
        this.initialSize = initialSize;
    }

    @Value("${spring.datasource.druid.clickhouse.max-active}")
    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }

    @Value("${spring.datasource.druid.clickhouse.min-idle}")
    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    @Value("${spring.datasource.druid.clickhouse.max-wait}")
    public void setMaxWait(Integer maxWait) {
        this.maxWait = maxWait;
    }

    /**
     * 分页查询插件
     *
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    @Bean(name = "mysqlDataSource")
    @Order(value = 5)
    @ConfigurationProperties(prefix = "spring.datasource.druid.mysql")
    public DataSource mysql() {
        return new DruidDataSource();
    }


    @Bean(name = "ckDataSource")
    @Order(value = 5)
    @ConfigurationProperties(prefix = "spring.datasource.druid.clickhouse")
    public DataSource clickhouse() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(url);
        datasource.setDriverClassName(driverClassName);
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setPassword(password);
        datasource.setUsername(username);
        return datasource;
    }

    @Bean
    @Primary
    @Order(value = 1)
    @DependsOn({ "mysqlDataSource", "ckDataSource"})
    public DynamicDataSource dataSource(@Qualifier("ckDataSource") DataSource ckDataSource, @Qualifier("mysqlDataSource") DataSource mysqlDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>(16);
        targetDataSources.put(DatabaseType.clickhouse_251, ckDataSource);
        targetDataSources.put(DatabaseType.mysql, mysqlDataSource);
        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(mysqlDataSource);
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean mfb = new MybatisSqlSessionFactoryBean();
        mfb.setDataSource(dataSource(clickhouse(), mysql()));
        Interceptor[] plugins = {paginationInterceptor()};
        mfb.setPlugins(plugins);
        mfb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/chenfan/**/dao/**/*.xml"));
        return mfb.getObject();
    }

    @Bean
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource(clickhouse(), mysql()));
    }
}


